home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Applications / Alpha.5.96 folder / Tcl / SystemCode / misc.tcl < prev    next >
Encoding:
Text File  |  1994-08-30  |  14.1 KB  |  592 lines  |  [TEXT/ALFA]

  1. #===========================================================================
  2. # Information about a selection or window.
  3. #===========================================================================
  4. proc wordCount {} {
  5.     if {[set chars [expr {[selEnd] - [getPos]}]]} {
  6.         set lines [expr {[lindex [posToRowCol [selEnd]] 0] - [lindex [posToRowCol [getPos]] 0]}]
  7.         set text [getSelect]
  8.     } else {
  9.         set chars [maxPos]
  10.         set lines [lindex [posToRowCol $chars] 0]
  11.         set text [getText 0 [maxPos]]
  12.     }
  13.     if {[regsub -all {[!=;.,\(\#\=\):\{\"\}]} $text " " ret]} {
  14.         set words [llength $ret]
  15.     } else {
  16.         set words [llength $text]
  17.     }
  18.     alertnote [format "%d chars, %d words, %d lines" $chars $words $lines]
  19. }
  20.  
  21. # proc matchingLines {} {
  22. #     if [catch {prompt "Regular expression:" ""} reg] return
  23. #     if {![string length $reg]} return
  24. #     set reg ^.*$reg.*$
  25. #     set pos [getPos]
  26. #     set matches 0
  27. #     while {![catch {search -f 1 -r 1 -m 0 -i 1 $reg $pos} mtch]} {
  28. #         append lines "\r" [format "%4d: " [lindex [posToRowCol [lindex $mtch 0]] 0]] [eval getText $mtch]
  29. #         set pos [lindex $mtch 1]
  30. #         incr matches
  31. #     }
  32. #     new
  33. #     insertText [format "%d matching lines\r-----" $matches] $lines "\r"
  34. # }
  35. proc matchingLines {} {
  36.     if [catch {prompt "Regular expression:" ""} reg] return
  37.     if {![string length $reg]} return
  38.     set reg ^.*$reg.*$
  39.     set pos 0
  40.     set fileName [lindex [winNames -f] 0]
  41.     set matches 0
  42.     while {![catch {search -f 1 -r 1 -m 0 -i 1 $reg $pos} mtch]} {
  43.         append lines "\r" [format "Line %d: " [lindex [posToRowCol [lindex $mtch 0]] 0]] [eval getText $mtch] "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t∞$fileName"
  44.         set pos [lindex $mtch 1]
  45.         incr matches
  46.     }
  47.     new -n {* Matching Lines *}
  48.     insertText [format "%d matching lines (<cr> to go to match)\r-----" $matches] $lines "\r"
  49.     select [nextLineStart [nextLineStart 0]] [nextLineStart [nextLineStart [nextLineStart 0]]]
  50.     
  51.     global winModes
  52.     set name [lindex [winNames] 0]
  53.     changeMode [set winModes($name) Brws]
  54.     setWinInfo dirty 0
  55.     setWinInfo read-only 1
  56. }
  57.  
  58. #=============================================================================
  59. # Random functions.
  60. #=============================================================================
  61.  
  62. #***********************************************************************
  63. #                                                                      *
  64. #   Comment box and uncomment box courtesy of Igor Mikolic-Torreira.   *
  65. #                                                                      *
  66. #**********************************************************************/
  67.  
  68. proc commentBox {} {
  69.  
  70. # Preliminaries
  71.  
  72.     if {[getPos] == [selEnd]} {
  73.         alertnote "Must select region to be commented."
  74.         return
  75.     }
  76.     global lastMode
  77.     watchCursor
  78.     
  79. # Set what the comment block will look like
  80.  
  81.     case $lastMode in {
  82.         "Text" {
  83.             set begComment "!"
  84.             set begComLen 1
  85.             set endComment "!"
  86.             set endComLen 1
  87.             set fillChar "!"
  88.             set spaceOffset 3
  89.         }
  90.         "Fort" {
  91.             set begComment "C"
  92.             set begComLen 1
  93.             set endComment "C"
  94.             set endComLen 1
  95.             set fillChar "C"
  96.             set spaceOffset 3
  97.         }
  98.         "Tcl" {
  99.             set begComment "#"
  100.             set begComLen 1
  101.             set endComment "#"
  102.             set endComLen 1
  103.             set fillChar "#"
  104.             set spaceOffset 3
  105.         }
  106.         "C" {
  107.             set begComment "/*"
  108.             set begComLen 2
  109.             set endComment "*/"
  110.             set endComLen 2
  111.             set fillChar "*"
  112.             set spaceOffset 3
  113.         }
  114.         "C++" {
  115.             set begComment "/*"
  116.             set begComLen 2
  117.             set endComment "*/"
  118.             set endComLen 2
  119.             set fillChar "*"
  120.             set spaceOffset 3
  121.         }
  122.         default {
  123.             alertnote "I don't know what comments should look like in this mode.  Sorry."
  124.             return
  125.         }
  126.     }
  127.     set aSpace " "
  128.  
  129. # First make sure we grab a full block of lines and adjust highlight
  130.  
  131.     set start [getPos]
  132.     set start [lineStart $start]
  133.     set end [selEnd]
  134.     set end [nextLineStart [expr $end-1]]
  135.     select $start $end
  136.  
  137. # Now get rid of any tabs
  138.     
  139.     if { $end < [maxPos] } then {
  140.         createTMark stopComment [expr $end+1]
  141.         tabsToSpaces
  142.         gotoTMark stopComment
  143.         set end [expr [getPos]-1]
  144.         removeTMark stopComment
  145.     } else {
  146.         tabsToSpaces
  147.         set end [maxPos]
  148.     }
  149.     select $start $end
  150.     set text [getText $start $end]
  151.     
  152. # Next turn it into a list of lines--possibly drop an empty 'last line'
  153.  
  154.     set lineList [split $text "\r"]
  155.     set emptyLine [lsearch $lineList {}]
  156.     if { $emptyLine != -1 } then {
  157.         set numLines [llength $lineList]
  158.         set lineList [lrange $lineList 0 [expr $numLines-2]]
  159.     }
  160.     set numLines [llength $lineList]
  161.     
  162. # Find the longest line length and determine the new line length
  163.  
  164.     set maxLength 0
  165.     foreach thisLine $lineList {
  166.         set thisLength [string length $thisLine]
  167.         if { $thisLength > $maxLength } then { 
  168.             set maxLength $thisLength 
  169.         }
  170.     }
  171.     set newLength [expr {$maxLength + 2 + 2*$spaceOffset}]
  172.     
  173. # Now create the top & bottom bars and a blank line
  174.  
  175.     set topBar $begComment
  176.     for { set i 0 } { $i < [expr {$newLength - $begComLen}] } { incr i } {
  177.         set topBar $topBar$fillChar
  178.     }
  179.     set botBar ""
  180.     for { set i 0 } { $i < [expr {$newLength - $endComLen}] } { incr i } {
  181.         set botBar $botBar$fillChar
  182.     }
  183.     set botBar $botBar$endComment
  184.     set blankLine $fillChar
  185.     for { set i 0 } { $i < [expr {$newLength - 2}] } { incr i } {
  186.         set blankLine $blankLine$aSpace
  187.     }
  188.     set blankLine $blankLine$fillChar
  189.     
  190. # For each line add stuff on left and spaces and stuff on right for box sides
  191. # and concatenate everything into 'text'.  Start with topBar; end with botBar
  192.  
  193.     set text $topBar\r$blankLine\r
  194.     
  195.     set frontStuff $fillChar
  196.     set backStuff $fillChar
  197.     for { set i 0 } { $i < $spaceOffset } { incr i } {
  198.         set frontStuff $frontStuff$aSpace  
  199.         set backStuff $aSpace$backStuff
  200.     }
  201.     set backStuffLen [string length $backStuff]
  202.     
  203.     for { set i 0 } { $i < $numLines } { incr i } {
  204.         set thisLine [lindex $lineList $i ]
  205.         set thisLine $frontStuff$thisLine
  206.         set thisLength [string length $thisLine]
  207.         set howMuchPad [expr {$newLength - $thisLength - $backStuffLen}]
  208.         for { set j 0 } { $j < $howMuchPad } { incr j } {
  209.             set thisLine $thisLine$aSpace 
  210.         }
  211.         set thisLine $thisLine$backStuff
  212.         set text $text$thisLine\r
  213.     }
  214.     
  215.     set text $text$blankLine\r$botBar\r
  216.     
  217. # Now replace the old stuff, turn spaces to tabs, and highlight
  218.  
  219.     replaceText    $start $end    $text
  220.     set end [expr {$start+[string length $text]}]
  221.     createTMark stopComment [expr $end+1]
  222.     select $start $end
  223.     spacesToTabs
  224.     gotoTMark stopComment
  225.     set end [expr [getPos]-1]
  226.     removeTMark stopComment
  227.     select $start $end
  228. }
  229.  
  230.  
  231.  
  232. proc uncommentBox {} {
  233.  
  234. # Preliminaries
  235.  
  236.     if {[getPos] == [selEnd]} {
  237.         alertnote "Must select region to be uncommented."
  238.         return
  239.     }
  240.     global lastMode
  241.     watchCursor
  242.     
  243. # Set what the comment block will look like
  244.  
  245.     case $lastMode in {
  246.         "Text" {
  247.             set begComment "!"
  248.             set begComLen 1
  249.             set endComment "!"
  250.             set endComLen 1
  251.             set fillChar "!"
  252.             set spaceOffset 3
  253.         }
  254.         "Fort" {
  255.             set begComment "C"
  256.             set begComLen 1
  257.             set endComment "C"
  258.             set endComLen 1
  259.             set fillChar "C"
  260.             set spaceOffset 3
  261.         }
  262.         "Tcl" {
  263.             set begComment "#"
  264.             set begComLen 1
  265.             set endComment "#"
  266.             set endComLen 1
  267.             set fillChar "#"
  268.             set spaceOffset 3
  269.         }
  270.         "C" {
  271.             set begComment "/*"
  272.             set begComLen 2
  273.             set endComment "*/"
  274.             set endComLen 2
  275.             set fillChar "*"
  276.             set spaceOffset 3
  277.         }
  278.         "C++" {
  279.             set begComment "/*"
  280.             set begComLen 2
  281.             set endComment "*/"
  282.             set endComLen 2
  283.             set fillChar "*"
  284.             set spaceOffset 3
  285.         }
  286.         default {
  287.             alertnote "I don't know what comments should look like in this mode.  Sorry."
  288.             return
  289.         }
  290.     }
  291.     set aSpace " "
  292.     set aTab \t
  293.  
  294. # First make sure we grab a full block of lines
  295.  
  296.     set start [getPos]
  297.     set start [lineStart $start]
  298.     set end [selEnd]
  299.     set end [nextLineStart [expr $end-1]]
  300.     set text [getText $start $end]
  301.  
  302. # Make sure we're at the start and end of the box
  303.  
  304.     set startOK [string first $begComment $text]
  305.     set endOK [string last $endComment $text]
  306.     set textLength [string length $text]
  307.     if { $startOK != 0 || ($endOK != [expr {$textLength-$endComLen-1}] || $endOK == -1) } then {
  308.         alertnote "You must highlight the entire comment box, including the borders."
  309.         return
  310.     }
  311.     
  312. # Now get rid of any tabs
  313.     
  314.     if { $end < [maxPos] } then {
  315.         createTMark stopComment [expr $end+1]
  316.         tabsToSpaces
  317.         gotoTMark stopComment
  318.         set end [expr [getPos]-1]
  319.         removeTMark stopComment
  320.     } else {
  321.         tabsToSpaces
  322.         set end [maxPos]
  323.     }
  324.     select $start $end
  325.     set text [getText $start $end]
  326.     
  327. # Next turn it into a list of lines--possibly drop an empty 'last line'
  328.  
  329.     set lineList [split $text "\r"]
  330.     set emptyLine [lsearch $lineList {}]
  331.     if { $emptyLine != -1 } then {
  332.         set numLines [llength $lineList]
  333.         set lineList [lrange $lineList 0 [expr $numLines-2]]
  334.     }
  335.     set numLines [llength $lineList]
  336.     
  337. # Delete the first and last lines, recompute number of lines
  338.  
  339.     set lineList [lreplace $lineList [expr $numLines-1] [expr $numLines-1] ]
  340.     set lineList [lreplace $lineList 0 0 ]
  341.     set numLines [llength $lineList]
  342.     
  343. # Eliminate 2nd and 2nd-to-last lines if they are empty
  344.  
  345.     set eliminate $fillChar$aSpace$aTab
  346.     set thisLine [lindex $lineList [expr $numLines-1]]
  347.     set thisLine [string trim $thisLine $eliminate]
  348.     if { [string length $thisLine] == 0 } then {
  349.         set lineList [lreplace $lineList [expr $numLines-1] [expr $numLines-1] ]
  350.     }
  351.     set thisLine [lindex $lineList 0]
  352.     set thisLine [string trim $thisLine $eliminate]
  353.     if { [string length $thisLine] == 0 } then {
  354.         set lineList [lreplace $lineList 0 0 ]
  355.     }
  356.     set numLines [llength $lineList]    
  357.     
  358. # For each line trim stuff on left and spaces and stuff on right and splice
  359.  
  360.     set dropFromLeft [expr $spaceOffset+1]
  361.     set text ""
  362.     for { set i 0 } { $i < $numLines } { incr i } {
  363.         set thisLine [lindex $lineList $i]
  364.         set thisLine [string trimright $thisLine $eliminate]
  365.         set thisLine [string range $thisLine $dropFromLeft end]
  366.         set text $text$thisLine\r
  367.     }
  368.         
  369. # Now replace the old stuff, convert spaces back to tabs
  370.  
  371.     replaceText    $start $end    $text
  372.     set end [expr {$start+[string    length $text]}]
  373.     createTMark stopComment [expr $end+1]
  374.     select $start $end
  375.     spacesToTabs
  376.     gotoTMark stopComment
  377.     set end [expr [getPos]-1]
  378.     removeTMark stopComment
  379.     select $start $end
  380. }
  381.  
  382.  
  383. #================================================================================
  384.  
  385. proc transposeWords {} {
  386.     global intelCutPaste
  387.     
  388.     set intel $intelCutPaste
  389.     set intelCutPaste 0
  390.     forwardWord
  391.     setMark
  392.     backwardWord
  393.     cut
  394.     deleteChar
  395.     forwardWord
  396.     insertText "\ "
  397.     paste
  398.     set intelCutPaste $intel
  399. }
  400.  
  401. proc transposeChars {} {
  402.      global intelCutPaste
  403.     
  404.     set intel $intelCutPaste
  405.     set intelCutPaste 0
  406.     setMark
  407.     forwardChar
  408.     cut
  409.     backwardChar
  410.     paste
  411.     forwardChar
  412.     set intelCutPaste $intel
  413. }
  414.  
  415. proc nextFunc {} {
  416.     searchFunc 1
  417. }
  418.  
  419. proc prevFunc {} {
  420.     searchFunc 0
  421. }
  422.  
  423. proc searchFunc {dir} {
  424.     global funcExpr
  425.     set pos [getPos]
  426.     select $pos
  427.     if ($dir==1) {
  428.         incr pos
  429.     } else {
  430.         set pos [expr $pos-1]
  431.     }
  432.     if {![catch {search -f $dir -i 1 -r 1 $funcExpr $pos} res]} {
  433.         eval select $res
  434.     }
  435. }
  436.  
  437. #===========================================================================
  438. # Comment routines.
  439. #===========================================================================
  440. proc commentPara {} {
  441. }
  442.  
  443.  
  444.  
  445. #===========================================================================
  446. # Sorting the selection.
  447. # AUTHOR: David C. Black     black@mpd.tandem.com
  448. #===========================================================================
  449. proc sortLines {} {
  450.     set ends [getEndpts]
  451.     set start [lindex $ends 0]
  452.     set end  [lindex $ends 1]
  453.     if {$start == $end} {
  454.         alertnote "You must highlight the section you wish to sort."
  455.         return
  456.     }
  457.     if {[lookAt [expr $end-1]] != "\r"} {
  458.         alertnote "The selection must consist only of complete lines."
  459.         return
  460.     }
  461.     set text [getText $start [expr {$end-1}]]
  462.     set text [join [lsort [split $text "\r"]] "\r"]
  463.     replaceText $start [expr {$end-1}] $text
  464.     select $start $end
  465. }
  466.  
  467.  
  468.  
  469. #===========================================================================
  470. # Dump all current settings into a file.
  471. #===========================================================================
  472. proc insertGlobalSettings {} {
  473.     uplevel #0 {
  474.         foreach var [info globals] {
  475.             if {![catch {set $var}]} {
  476.                 insertText "set " $var " \{" [set $var] "\}\r"
  477.             }
  478.         }
  479.     }
  480. }
  481.  
  482.  
  483. #================================================================================
  484. # Substitute global variables in possibly nested list.
  485. #================================================================================
  486. proc subVars {words} {
  487.     global silly
  488.     global a
  489.     set silly $words
  490.     set out {}
  491.     foreach a $words {
  492.         if {[llength $a] == 1} {
  493.             lappend out [uplevel #0 {eval set x $a}]
  494.         } else {
  495.             lappend out [subVars $a]
  496.         }
  497.     }
  498.     return $out
  499. }
  500.  
  501. #================================================================================
  502. # Block shift left and right.
  503. #================================================================================
  504. set shiftChar    "\t"
  505.  
  506. proc shiftLeft {} {
  507.     global shiftChar
  508.     
  509.      set start [lineStart [getPos]]
  510.      set end [nextLineStart [expr [selEnd] - 1]]
  511.     if {$start >= $end} {set end [nextLineStart $start]}
  512.     
  513.     set text [split [getText $start [expr $end - 1]] "\r"]
  514.     
  515.     set textout ""
  516.     
  517.     foreach line $text {
  518.         if {[string index $line 0] == $shiftChar} {
  519.             lappend textout [string range $line 1 end]
  520.         } else {
  521.             lappend textout $line
  522.         }
  523.     }
  524.  
  525.     set text [join $textout "\r"]    
  526.     replaceText $start [expr $end - 1] $text
  527.     select $start [expr 1 + $start + [string length $text]]
  528. }
  529.  
  530.  
  531. proc shiftRight {} {
  532.     global    shiftChar
  533.     
  534.     set start [lineStart [getPos]]
  535.     set end [nextLineStart [expr [selEnd] - 1]]
  536.     if {$start >= $end} {set end [nextLineStart $start]}
  537.     
  538.     set text [split [getText $start [expr $end - 1]] "\r"]
  539.     
  540.     set textout ""
  541.     
  542.     foreach line $text {
  543.         lappend textout $shiftChar$line
  544.     }
  545.     
  546.     set text [join $textout "\r"]    
  547.     replaceText $start [expr $end - 1] $text
  548.     select $start [expr 1 + $start + [string length $text]]
  549. }
  550.  
  551.  
  552.  
  553. # rglob [option list] dir pat
  554. # 'dir' should be a properly formed directory, ending w/ a ':'. 'pat' should be 
  555. # a simple pattern w/ no directory specifications (i.e. "*.c").
  556. proc rglob {optlist dir pat} {
  557.  
  558.     set cmd [concat glob $optlist]
  559.     lappend cmd $dir$pat
  560.     if {[catch {eval $cmd} files]} {
  561.         set files ""
  562.     }
  563.     
  564.     if {![catch {glob $dir*} all]} {
  565.         foreach f $all {
  566.             if {[file isdir $f]} {
  567.                 set files [concat $files [rglob $optlist $f: $pat]]
  568.             }
  569.         }
  570.     }
  571.     return $files
  572. }
  573.  
  574.  
  575. proc switchApp {} {
  576.     set procs ""
  577.     foreach p [processes] {
  578.         lappend procs [lindex $p 0]
  579.     }
  580.     set to [listpick -p "Switch to app:" $procs]
  581.     if {[string length $to]} {
  582.         switchTo $to
  583.     }
  584. }
  585.  
  586.  
  587. proc selectAll {} {
  588.     select 0 [maxPos]
  589. }
  590.  
  591.  
  592.